home *** CD-ROM | disk | FTP | other *** search
- /*
- sharp.c -- perform sharp, disjoint sharp, and intersection
- */
-
- #include "espresso.h"
-
- long start_time;
-
-
- /* cv_sharp -- form the sharp product between two covers */
- pcover cv_sharp(A, B)
- pcover A, B;
- {
- pcube last, p;
- pcover T;
-
- T = new_cover(0);
- foreach_set(A, last, p)
- T = sf_union(T, cb_sharp(p, B));
- return T;
- }
-
-
- /* cb_sharp -- form the sharp product between a cube and a cover */
- pcover cb_sharp(c, T)
- pcube c;
- pcover T;
- {
- if (T->count == 0) {
- T = sf_addset(new_cover(1), c);
- } else {
- start_time = ptime();
- T = cb_recur_sharp(c, T, 0, T->count-1, 0);
- }
- return T;
- }
-
-
- /* recursive formulation to provide balanced merging */
- pcover cb_recur_sharp(c, T, first, last, level)
- pcube c;
- pcover T;
- int first, last, level;
- {
- pcover temp, left, right;
- int middle;
-
- if (first == last) {
- temp = sharp(c, GETSET(T, first));
- } else {
- middle = (first + last) / 2;
- left = cb_recur_sharp(c, T, first, middle, level+1);
- right = cb_recur_sharp(c, T, middle+1, last, level+1);
- temp = cv_intersect(left, right);
- if ((debug & SHARP) && level < 4) {
- printf("# SHARP[%d]: %4d = %4d x %4d, time = %s\n",
- level, temp->count, left->count, right->count,
- print_time(ptime() - start_time));
- (void) fflush(stdout);
- }
- free_cover(left);
- free_cover(right);
- }
- return temp;
- }
-
-
- /* sharp -- form the sharp product between two cubes */
- pcover sharp(a, b)
- pcube a, b;
- {
- register int var;
- register pcube d=cube.temp[0], temp=cube.temp[1], temp1=cube.temp[2];
- pcover r = new_cover(cube.num_vars);
-
- if (cdist0(a, b)) {
- set_diff(d, a, b);
- for(var = 0; var < cube.num_vars; var++) {
- if (! setp_empty(set_and(temp, d, cube.var_mask[var]))) {
- set_diff(temp1, a, cube.var_mask[var]);
- set_or(GETSET(r, r->count++), temp, temp1);
- }
- }
- } else {
- r = sf_addset(r, a);
- }
- return r;
- }
-
- pcover make_disjoint(A)
- pcover A;
- {
- pcover R, new;
- register pset last, p;
-
- R = new_cover(0);
- foreach_set(A, last, p) {
- new = cb_dsharp(p, R);
- R = sf_append(R, new);
- }
- return R;
- }
-
-
- /* cv_dsharp -- disjoint-sharp product between two covers */
- pcover cv_dsharp(A, B)
- pcover A, B;
- {
- register pcube last, p;
- pcover T;
-
- T = new_cover(0);
- foreach_set(A, last, p) {
- T = sf_union(T, cb_dsharp(p, B));
- }
- return T;
- }
-
-
- /* cb1_dsharp -- disjoint-sharp product between a cover and a cube */
- pcover cb1_dsharp(T, c)
- pcover T;
- pcube c;
- {
- pcube last, p;
- pcover R;
-
- R = new_cover(T->count);
- foreach_set(T, last, p) {
- R = sf_union(R, dsharp(p, c));
- }
- return R;
- }
-
-
- /* cb_dsharp -- disjoint-sharp product between a cube and a cover */
- pcover cb_dsharp(c, T)
- pcube c;
- pcover T;
- {
- pcube last, p;
- pcover Y, Y1;
-
- if (T->count == 0) {
- Y = sf_addset(new_cover(1), c);
- } else {
- Y = new_cover(T->count);
- set_copy(GETSET(Y,Y->count++), c);
- foreach_set(T, last, p) {
- Y1 = cb1_dsharp(Y, p);
- free_cover(Y);
- Y = Y1;
- }
- }
- return Y;
- }
-
-
- /* dsharp -- form the disjoint-sharp product between two cubes */
- pcover dsharp(a, b)
- pcube a, b;
- {
- register pcube mask, diff, and, temp, temp1 = cube.temp[0];
- int var;
- pcover r;
-
- r = new_cover(cube.num_vars);
-
- if (cdist0(a, b)) {
- diff = set_diff(new_cube(), a, b);
- and = set_and(new_cube(), a, b);
- mask = new_cube();
- for(var = 0; var < cube.num_vars; var++) {
- /* check if position var of "a and not b" is not empty */
- if (! setp_disjoint(diff, cube.var_mask[var])) {
-
- /* coordinate var equals the difference between a and b */
- temp = GETSET(r, r->count++);
- (void) set_and(temp, diff, cube.var_mask[var]);
-
- /* coordinates 0 ... var-1 equal the intersection */
- INLINEset_and(temp1, and, mask);
- INLINEset_or(temp, temp, temp1);
-
- /* coordinates var+1 .. cube.num_vars equal a */
- set_or(mask, mask, cube.var_mask[var]);
- INLINEset_diff(temp1, a, mask);
- INLINEset_or(temp, temp, temp1);
- }
- }
- free_cube(diff);
- free_cube(and);
- free_cube(mask);
- } else {
- r = sf_addset(r, a);
- }
- return r;
- }
-
- /* cv_intersect -- form the intersection of two covers */
-
- #define MAGIC 500 /* save 500 cubes before containment */
-
- pcover cv_intersect(A, B)
- pcover A, B;
- {
- register pcube pi, pj, lasti, lastj, pt;
- pcover T, Tsave = NULL;
-
- /* How large should each temporary result cover be ? */
- T = new_cover(MAGIC);
- pt = T->data;
-
- /* Form pairwise intersection of each cube of A with each cube of B */
- foreach_set(A, lasti, pi) {
- foreach_set(B, lastj, pj) {
- if (cdist0(pi, pj)) {
- (void) set_and(pt, pi, pj);
- if (++T->count >= T->capacity) {
- if (Tsave == NULL)
- Tsave = sf_contain(T);
- else
- Tsave = sf_union(Tsave, sf_contain(T));
- T = new_cover(MAGIC);
- pt = T->data;
- } else
- pt += T->wsize;
- }
- }
- }
-
-
- if (Tsave == NULL)
- Tsave = sf_contain(T);
- else
- Tsave = sf_union(Tsave, sf_contain(T));
- return Tsave;
- }
-